package com.qixin.web.controller.push;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qixin.api.service.ComChargeInfoService;
import com.qixin.util.cache.EhcacheUtil;
import com.qixin.util.chargeInterfce.Charge.EvcsResponse;
import com.qixin.util.chargeInterfce.Charge.Test;
import com.qixin.util.chargeInterfce.Charge.bean.ChargeDetails;
import com.qixin.util.chargeInterfce.Charge.bean.StopChargeBean;
import com.qixin.util.chargeInterfce.QiXinPublic.StarInterFce;
import com.qixin.util.weixin.WxpubOAuth;
import com.qixin.web.bean.ConnectorStatusInfos;
import com.qixin.web.util.SessionUtil;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Zhang on 2018/11/6.
 * 消息推送接口
 */
@Controller
public class PushController {
    private static ReentrantLock rwl = new ReentrantLock();
    private Logger logger = LoggerFactory.getLogger(PushController.class);
    @Autowired
    ComChargeInfoService comChargeInfoServicel;

    //获取token 缓存7200S 加入  写锁
    @RequestMapping("/query_token")
    @ResponseBody
    public JSONObject query_token() throws Exception {
        logger.info("试图请求token");
        String token = (String) EhcacheUtil.get("Authorization", "token");
        EvcsResponse evcsResponse = new EvcsResponse();
        Map map = new HashMap<>();
        if (token != null) {
            map.put("SuccStat", 0);
            map.put("TokenAvailableTime", 7200);
            map.put("OperatorID", Test.SERVER_OPERATORID);
            map.put("FailReason", 0);
            map.put("AccessToken", token);
            evcsResponse.setMsg("success");
            evcsResponse.setRet(0);
            evcsResponse.setData(map);
            String result = Test.responseEncode(null, evcsResponse);
            JSONObject itemJSONObj = JSONObject.parseObject(result);
            return itemJSONObj;
        } else {
            //打开写入锁
            rwl.lock();
            try {
                String newToken = UUID.randomUUID().toString().replace("-", "");
                EhcacheUtil.put("Authorization", "token", newToken);
                map.put("SuccStat", 0);
                map.put("TokenAvailableTime", 7200);
                map.put("OperatorID", Test.SERVER_OPERATORID);
                map.put("FailReason", 0);
                map.put("AccessToken", newToken);
                evcsResponse.setMsg("success");
                evcsResponse.setRet(0);
                evcsResponse.setData(map);
                String result = Test.responseEncode(null, evcsResponse);
                JSONObject itemJSONObj = JSONObject.parseObject(result);
                return itemJSONObj;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            } finally {
                //解开锁
                rwl.unlock();
            }

        }
    }

    //接收推送设备变化推送    // TODO: 2018/11/14 返回值类型有反斜杠  但是 token没有 同样的写法  不同的结果 暂时无法解决。
    @RequestMapping("/notification_stationStatus")
    @ResponseBody
    public JSONObject notification_stationStatus(HttpServletRequest request, @RequestBody JSONObject ConnectorStatusInfo) throws Exception {
        logger.info("设备有变化推送 ");
        logger.info("String参数：" + ConnectorStatusInfo);
        //解密后把推送数据 转成map
        Map requestParamMap = Test.responseDecode(ConnectorStatusInfo.toJSONString());
        //从map中获取 推送的数据包   转成实体类
        ConnectorStatusInfos connectorStatusInfos = JSONObject.parseObject(requestParamMap.get("ConnectorStatusInfo") + "", ConnectorStatusInfos.class);
        logger.info("解密后的data： " + connectorStatusInfos.toString());

        if (!TokenIs(request)) {
            EvcsResponse evcsResponse = new EvcsResponse();
            evcsResponse.setRet(1);
            evcsResponse.setMsg("Token验证失败");
            String result = Test.responseEncode(null, evcsResponse);
            JSONObject itemJSONObj = JSONObject.parseObject(result);
            return itemJSONObj;
        }
        // logger.info(ConnectorStatusInfo.toString());
        EvcsResponse evcsResponse = new EvcsResponse();
        Map map = new HashMap<>();
        map.put("Status", 0);
        evcsResponse.setMsg("success");
        evcsResponse.setRet(0);
        evcsResponse.setData(map);
        //  String result =StringEscapeUtils.unescapeJavaScript(Test.responseEncode(null, evcsResponse)) ;
        String result = Test.responseEncode(null, evcsResponse);
        JSONObject itemJSONObj = JSON.parseObject(result);
        return itemJSONObj;
    }

    //接收推送启动状态
    @RequestMapping("/notification_start_charge_result")
    @ResponseBody
    public JSONObject notification_start_charge_result(HttpServletRequest request, @RequestBody JSONObject StratParam) throws Exception {
        //解密后把推送数据 转成map
        Map requestParamMap = Test.responseDecode(StratParam.toJSONString());
        if (!TokenIs(request)) {
            EvcsResponse evcsResponse = new EvcsResponse();
            evcsResponse.setRet(1);
            evcsResponse.setMsg("Token验证失败");
            String result = Test.responseEncode(null, evcsResponse);
            logger.info("Token验证失败");
            JSONObject itemJSONObj = JSONObject.parseObject(result);
            return itemJSONObj;
        }
        //获取 订单号
        String order = requestParamMap.get("StartChargeSeq")+"";
        String openId = (String) EhcacheUtil.get("chargeStat", order + "Data");
        String carPlant = (String) EhcacheUtil.get("chargeCarPlant",order + "Data");
        //如果缓存中还有openid  说明还未向该用户发送过消息 则向该用户推送消息
        if (openId != null) {

            //从缓存中拿 当前订单的用户手机号和id
            String chargeUserPhone = EhcacheUtil.get("chargeUserPhone", order+ "Data") + "";
            Long chargeUserId = Long.parseLong(EhcacheUtil.get("chargeUserId", order + "Data")+"");
              logger.info("推送的chargeUserPhone"+chargeUserPhone);
              logger.info("推送的chargeUserId"+chargeUserId);
            //拿完后立即删除缓存
            EhcacheUtil.remove("chargeUserPhone", order + "Data");
            EhcacheUtil.remove("chargeUserId", order + "Data");
            if (Integer.parseInt(requestParamMap.get("StartChargeSeqStat") + "") == 2&&chargeUserPhone!=null&&chargeUserId!=null) {
                //保存充电记录
                comChargeInfoServicel.weChartInsert(requestParamMap,chargeUserId, chargeUserPhone, carPlant);
            }
            logger.info("本次推送是推送接口发送的消息,准备发给的openid="+openId);
            String messge = WxpubOAuth.sendUseMessage(openId,order, carPlant, requestParamMap.get("StartChargeSeqStat") + "", requestParamMap.get("StartTime") + "", null);
            EhcacheUtil.remove("chargeStat",order+ "Data");

        }
        Map map = new HashMap<>();
        map.put("StartChargeSeq",order);
        map.put("SuccStat", 0);
        EvcsResponse evcsResponse = new EvcsResponse();
        evcsResponse.setRet(0);
        evcsResponse.setMsg("");
        evcsResponse.setData(map);
        String result = Test.responseEncode(null, evcsResponse);
        JSONObject itemJSONObj = JSONObject.parseObject("");
        return itemJSONObj;
    }

    //推送充电状态    // TODO: 2018/11/13
    @RequestMapping("/notification_equip_charge_status")
    @ResponseBody
    public JSONObject notification_equip_charge_status(HttpServletRequest request, @RequestBody JSONObject jsonObject) throws Exception {
     //   logger.info("推送的充电状态：" + jsonObject);
        //解密后把推送数据 转成map
        Map requestParamMap = Test.responseDecode(jsonObject.toJSONString());

        if (!TokenIs(request)) {
            EvcsResponse evcsResponse = new EvcsResponse();
            evcsResponse.setRet(1);
            evcsResponse.setMsg("Token验证失败");
            String result = Test.responseEncode(null, evcsResponse);
            logger.info("Token验证失败");
            JSONObject itemJSONObj = JSONObject.parseObject(result);
            return itemJSONObj;
        }
        Map map = new HashMap<>();
        map.put("StartChargeSeq", requestParamMap.get("StartChargeSeq"));
        map.put("SuccStat", 0);
        EvcsResponse evcsResponse = new EvcsResponse();
        evcsResponse.setRet(0);
        evcsResponse.setMsg("");
        evcsResponse.setData(map);
        String result = Test.responseEncode(null, evcsResponse);
        JSONObject itemJSONObj = JSONObject.parseObject(result);
        return itemJSONObj;
    }

    // 推送充电订单信息    // TODO: 2018/11/13
    @RequestMapping("/notification_charge_order_info  ")
    @ResponseBody
    public JSONObject notification_charge_order_info(HttpServletRequest request, @RequestBody StopChargeBean stopChargeBean) throws Exception {
        logger.info(" 推送充电订单信息：" + stopChargeBean.toString());
        if (!TokenIs(request)) {
            EvcsResponse evcsResponse = new EvcsResponse();
            evcsResponse.setRet(1);
            evcsResponse.setMsg("Token验证失败");
            String result = Test.responseEncode(null, evcsResponse);
            logger.info("Token验证失败");
            JSONObject itemJSONObj = JSONObject.parseObject(result);
            return itemJSONObj;
        }
        Map map = new HashMap<>();
        map.put("StartChargeSeq", stopChargeBean.getStartChargeSeq());
        map.put("SuccStat", 0);
        EvcsResponse evcsResponse = new EvcsResponse();
        evcsResponse.setRet(0);
        evcsResponse.setMsg("");
        evcsResponse.setData(map);
        String result = Test.responseEncode(null, evcsResponse);
        JSONObject itemJSONObj = JSONObject.parseObject(result);
        return itemJSONObj;
    }


    //接收推送停止状态  电池充满电自动停止  需要另外模板
    @RequestMapping("/notification_stop_charge_result")
    @ResponseBody
    public JSONObject notification_stop_charge_result(HttpServletRequest request, @RequestBody JSONObject jsonObject) throws Exception {
        logger.info("stop有推送");

        if (!TokenIs(request)) {
            EvcsResponse evcsResponse = new EvcsResponse();
            evcsResponse.setRet(1);
            evcsResponse.setMsg("Token验证失败");
            String result = Test.responseEncode(null, evcsResponse);
            JSONObject itemJSONObj = JSONObject.parseObject(result);
            return itemJSONObj;
        }

        //解密后把推送数据 转成map
        Map requestParamMap = Test.responseDecode(jsonObject.toJSONString());
        //推送了以后  重新查一遍详细数据
        StarInterFce starInterFce = new StarInterFce();
        String token = starInterFce.getToken();
        // 结果 转实体类
        String useReslut = starInterFce.findUseCharge(token, requestParamMap.get("StartChargeSeq") + "");
        StopChargeBean stopChargeBean = JSONObject.parseObject(useReslut, StopChargeBean.class);
        ChargeDetails chargeDetails = stopChargeBean.getChargeDetails().get(0);
        //获取订单
        String order=  requestParamMap.get("StartChargeSeq")+"" ;
        String openId = (String) EhcacheUtil.get("stopCharge", requestParamMap.get("StartChargeSeq") + "Data");
        EhcacheUtil.remove("stopCharge", order + "Data");
        //如果缓存中还有openid  说明还未向该用户发送过消息 则向该用户推送消息
        if (openId != null) {
            logger.info("本次停止通知是推送通知");
            String messge = WxpubOAuth.sendStopMessage(openId,order, stopChargeBean.getStartChargeSeqStat(), chargeDetails.getDetailStartTime(), chargeDetails.getDetailEndTime(), stopChargeBean.getTotalMoney());
            comChargeInfoServicel.weChartUpdate(stopChargeBean,  EhcacheUtil.get("chargeCarPlant",order + "Data")+"");
            EhcacheUtil.remove("chargeCarPlant",order + "Data");
        }
        //成功后返回数据
        Map map = new HashMap<>();
        map.put("StartChargeSeq", requestParamMap.get("StartChargeSeq"));
        map.put("SuccStat", 0);
        map.put("FailReason", 0);
        EvcsResponse evcsResponse = new EvcsResponse();
        evcsResponse.setRet(0);
        evcsResponse.setMsg("");
        evcsResponse.setData(map);
        String result = Test.responseEncode(null, evcsResponse);
        JSONObject itemJSONObj = JSONObject.parseObject(result);
        return itemJSONObj;
    }


    //判断请求头是否携带有正确的token凭据
    public   boolean TokenIs(HttpServletRequest request) {
        if (request.getHeader("Authorization") == null) {
            return true;
        }
        String requestToken;
        String token;
        try {
            requestToken = request.getHeader("Authorization");
         //   logger.info("本次推送请求 携带的token是：" + requestToken);
            token = (String) EhcacheUtil.get("Authorization", "token");
          //  logger.info("本次推送请求 缓存的token是: Bearer " + token);
            return /*requestToken.equals("Bearer " + token)*/true;
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
    }

}
